package com.zx.account.controller;

import com.google.common.collect.Lists;
import com.zx.account.controller.vo.AccountVo;
import com.zx.account.controller.vo.PieVo;
import com.zx.account.entity.Month;
import com.zx.account.entity.User;
import com.zx.account.model.ATypeDetailDto;
import com.zx.account.model.ATypeDto;
import com.zx.account.service.ATypeService;
import com.zx.account.service.AccountService;
import com.zx.account.service.MonthService;
import com.zx.util.NumUtil;
import com.zx.util.SessionDataUtil;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;


/**
 * @version v1.0
 * @Project: managing-self
 * @Title: AccountController
 * @Description: 月消费报表
 * @author: zhangxue
 * @date: 2019年10月4日下午10:15:35
 * @company: 未知
 * @Copyright: Copyright (c) 2015
 */
@Controller
@RequestMapping("/account")
public class AccountMonthController {

    @Autowired
    private AccountService accountService;

    @Autowired
    private ATypeService aTypeService;

    @Autowired
    private MonthService monthService;

    /**
     * 初始化报表模块
     *
     * @param m
     * @return
     */
    @RequestMapping("/monthView")
    public ModelAndView monthView(ModelAndView m) {
        User user = SessionDataUtil.getUserInfo();
        List<Month> li = monthService.getByUserId(user.getId());
        // 用来存储年信息，只记录年份
        List<Integer> year = li.stream()
                .map(Month::getAYear)
                .distinct()
                .sorted((a1, a2) -> ~a1.compareTo(a2))
                .collect(Collectors.toList());

        Map<Integer, List<Integer>> yearMonths = new HashMap<>();
        for (Month month : li) {
            if (!yearMonths.containsKey(month.getAYear())) {
                yearMonths.put(month.getAYear(), new ArrayList<>());
            }
            yearMonths.get(month.getAYear()).add(month.getAMonth());
        }

        m.addObject("yearMonths", yearMonths);
        m.addObject("years", year);
        m.setViewName("account/monthView");
        return m;
    }

    /**
     * 按月份查询
     *
     * @param date
     * @return
     */
    @RequestMapping("/month")
    @ResponseBody
    public Map<String, Object> lookMon(String date) {
        User user = SessionDataUtil.getUserInfo();
        Map<String, Object> map = new HashMap<String, Object>();
        int year;
        int month;
        String[] split = date.split("-");
        if (split.length > 1) {
            year = Integer.parseInt(split[0]);
            month = Integer.parseInt(split[1]);
        } else {
            year = Integer.parseInt(split[0]);
            month = 0;
        }
        List<AccountVo> li = this.accountService.getByMonth(year, month, user.getId());
        BigDecimal sum = AccountQueryController.getSum(li);// 计算总的消费金额
        long days = AccountQueryController.getDays(li);// 计算总的天数
        double avg = days == 0 ? 0 : sum.doubleValue() / days;// 计算平均日消费

        this.getPie(map, li, user.getId());
        map.put("list", li);
        map.put("sum", sum);
        map.put("avg", String.format("%.1f", avg));
        map.put("num", days);
        return map;
    }

    // ********************************如下类中的工具方法*********************************

    /**
     * 生成饼形图的数据
     *
     * @param map
     * @param pojo
     */
    public void getPie(Map<String, Object> map, List<AccountVo> pojo, int userId) {
        // 查询所有的消费类别
        List<ATypeDto> types = this.aTypeService.getByUserId(userId);
        Map<Integer, String> typeMap = types.stream().collect(Collectors.toMap(ATypeDto::getId, ATypeDto::getName));

        List<ATypeDetailDto> detailDtos = this.aTypeService.getDetailByUserId(userId);
        Map<Integer, String> detailMap = detailDtos.stream()
                .collect(Collectors.toMap(ATypeDetailDto::getId, ATypeDetailDto::getName));

        // 计算所有消费的金额
        double sum = NumUtil.sum(pojo, AccountVo::getPrice).doubleValue();

        // 分组数据
        Map<Integer, Map<Integer, List<AccountVo>>> capData = pojo.stream()
                .collect(Collectors.groupingBy(AccountVo::getTId, Collectors.groupingBy(AccountVo::getTDId)));

        List<PieVo> pie = Lists.newArrayList();
        StringBuffer tableHtml = new StringBuffer();
        for (int i = 0; i < types.size(); i++) {
            ATypeDto type = types.get(i);

            Map<Integer, List<AccountVo>> typeData = capData.get(type.getId());

            PieVo p1 = new PieVo(type.getName(), 0, 0, Lists.newArrayList());

            double typeSum = 0;
            if (typeData != null) {
                for (Entry<Integer, List<AccountVo>> entry : typeData.entrySet()) {
                    Integer tdId = entry.getKey();
                    String tdName = detailMap.getOrDefault(tdId, "");
                    double detailSum = NumUtil.sum(entry.getValue(), AccountVo::getPrice).doubleValue();

                    p1.getChildren().add(new PieVo(tdName, detailSum, NumUtil.format(detailSum * 100 / sum), null));

                    typeSum += detailSum;
                }
            }

            // 生成table
            tableHtml.append("<tr><td>").append(types.get(i).getName()).append("<td>").append(typeSum).append("</td>")
                    .append("</td></tr>");

            p1.setValue(typeSum);
            p1.setPercent(NumUtil.format(typeSum * 100 / sum));
            pie.add(p1);

        }

        map.put("table", tableHtml.toString());
        map.put("pie", pie);
    }

}
